using PBO.Data;
using PBO.Data.Util;
using System;
using System.Linq;

namespace PBO.Game.BattleClass
{
    public partial class Pokemon
    {
        public PokemonData Data { get; private set; }

        public Pokemon(PokemonCustomInfo info, BattleTeam team, bool ppUp)
        {
            this.Data = GameService.GetPokemon(info.Identity);
            this.MyTeam = team;
            mSelMoves = new Move[4];

            this.NameBase = this.Data.NameBase;

            _type1 = this.Data.Type1;
            _type2 = this.Data.Type2;
            this.BattleState.TempType1 = this.Data.Type1;
            this.BattleState.TempType2 = this.Data.Type2;

            LoadImage(this.Data);

            this.Iv = new BaseStats(info.Iv);
            this.Ev = new BaseStats(info.Ev);
            this.Gender = info.Gender;
            this.Nature = info.Nature;
            this.LV = info.LV;
            this.NickName = info.NickName;
            this.mItem = info.Item;
            this.mSelTrait = info.Ability;

            for (int i = 0; i < 4; i++)
            {
                if (info.Moves[i] != 0)
                {
                    this.SetMove(i + 1, info.Moves[i], ppUp ? 3 : 0);
                }
            }

            if (GetSelTrait() == Trait.SlowStart || GetSelTrait() == Trait.Multitype)
                RaiseTrait();

            this.BaseValue = CalculateHelper.GetBaseValue(this.Nature, this.Data.BaseStats, this.Iv, this.Ev, this.LV);
            this.MaxHp = this.BaseValue.Hp;
            SetHP(this.MaxHp);
        }

        //public Pokemon(PokemonCustomInfo info, Team myTeamValue, bool ppUp)
        //{
        //    this.Data = GameService.GetPokemon(info.Identity);
        //    //MyTeam = myTeamValue;

        //    mSelMoves = new Move[4];

        //    this.NameBase = this.Data.NameBase;

        //    _type1 = this.Data.Type1;
        //    _type2 = this.Data.Type2;
        //    this.BattleState.TempType1 = this.Data.Type1;
        //    this.BattleState.TempType2 = this.Data.Type2;

        //    LoadImage(this.Data);

        //    this.Iv = new BaseStats(info.Iv);
        //    this.Ev = new BaseStats(info.Ev);
        //    this.Gender = info.Gender;
        //    this.Nature = info.Nature;
        //    this.LV = info.LV;
        //    this.NickName = info.NickName;
        //    this.mItem = info.Item;
        //    this.mSelTrait = info.Ability;

        //    for (int i = 0; i < 4; i++)
        //    {
        //        if (info.Moves[i] != 0)
        //        {
        //            this.SetMove(i + 1, info.Moves[i], ppUp ? 3 : 0);
        //        }
        //    }

        //    if (GetSelTrait() == Trait.错失先机 || GetSelTrait() == Trait.多元系)
        //        RaiseTrait();

        //    this.BaseValue = CalculateHelper.GetBaseValue(this.Nature, this.Data.BaseStats, this.Iv, this.Ev, this.LV);
        //    this.MaxHp = this.BaseValue.Hp;
        //    SetHP(this.MaxHp);
        //}

        public string NickName { get; private set; }
        public byte LV { get; private set; }
        public PokemonGender Gender { get; private set; }
        public PokemonNature Nature { get; private set; }

        public string CustomName
        {
            get
            {
                return NickName;
                //if (Properties.Settings.Default.CustomName == 0)
                //{
                //    return NickName;
                //}
                //else
                //{
                //    return NameBase;
                //}
            }
        }

        public string GetNameString()
        {
            return string.Format("{0} 的 {1}", MyTeam.PlayerName, CustomName);
        }

        public Pokemon Friend
        {
            get
            {
                //return this.BattleTeam.Owner.Group.SelectedPokemon.FirstOrDefault(p => !object.ReferenceEquals(p, this));
                return MyTeam.SelectedPokemon.FirstOrDefault(p => !object.ReferenceEquals(p, this));
            }
        }

        /// <summary>
        /// 技能变身
        /// </summary>
        public void Transfrom(Pokemon pm)
        {
            BattleState.transfrom = true;
            BattleState.transTemp = pm.Data;

            SetAttackValue(pm.GetAttackValue());
            SetDefenceValue(pm.GetDefenceValue());
            SpAttackValue = pm.SpAttackValue;
            SpDefenceValue = pm.SpDefenceValue;
            SpeedValue = pm.SpeedValue;

            for (int i = 1; i <= 4; i++)
            {
                if (pm.GetSelMove(i) == null)
                {
                    SetTempMove(i, null);
                    continue;
                }
                Move move = new Move(pm.GetSelMove(i).Data.Id, this, 0);
                move.PP = 5;
                SetTempMove(i, move);
            }

            BattleState.AbilityLv = (BattleStats)pm.BattleState.AbilityLv.Clone();
            //BattleState.AttackLV = pm.AttackLV;
            //BattleState.DefenceLV = pm.DefenceLV;
            //BattleState.SpDefenceLV = pm.SpDefenceLV;
            //BattleState.SpDefenceLV = pm.SpDefenceLV;
            //BattleState.SpeedLV = pm.SpeedLV;
            //BattleState.evasionLV = pm.BattleState.evasionLV;

            this.Type1 = pm.Type1;
            this.Type2 = pm.Type2;
            SetTrait(pm.GetSelTrait(true));
            if (UsedItem.IsChoiceItem()) UsedItem = Item.None;
            OnImageChanged();
        }

        public void ShapeShift(PokemonData pmData)
        {
            //BattleState.shapeShift = true;
            BattleState.transTemp = pmData;
            //Type1 = BattleData.GetTypeData(pmData.Type1);
            //Type2 = BattleData.GetTypeData(pmData.Type2);

            this.Type1 = pmData.Type1;
            this.Type2 = pmData.Type2;

            this.BaseValue = CalculateHelper.GetBaseValue(this.Nature, pmData.BaseStats, this.Iv, this.Ev, this.LV);

            OnImageChanged();
        }

        public void ChangePM(PlayerBattleMove move, bool pass)
        {
            MyTeam.Group.ChangePokemon(this, move.MoveIndex - 1, pass);
        }

        //public void ChangePM(int index, bool pass)
        //{
        //    MyTeam.Group.ChangePokemon(this, index - 1, pass);
        //}

        public void Showed()
        {
            Trait[] array = { Trait.Intimidate, Trait.Drizzle, Trait.Drought, Trait.SlowStart, Trait.SandStream, Trait.SnowWarning, Trait.Frisk, Trait.Trace, Trait.Download, Trait.Forewarn, Trait.Anticipation, Trait.Truant, Trait.Pressure };
            
            if (array.Contains(this.GetSelTrait()))
            {
                RaiseTrait();
            }
            if (GetItem() == Item.WhiteHerb)
            {
                RaiseItem();
            }
        }

        /// <summary>
        /// 是否可以接力
        /// </summary>
        public bool Pass()
        {
            if (!this.CanChange())
                return false;
            BattleState.pass = true;
            return true;
        }

        /// <summary>
        /// 吹吼强制换人
        /// </summary>
        public bool MakedToSwap(Pokemon target)
        {
            if (BattleState.ingrain || (GetSelTrait() == Trait.SuctionCups && target.GetSelTrait() != Trait.MoldBreaker) || !this.CanChange())
                return false;
            var list = MyTeam.CanChangePokemons.ToArray();
            var p2 = MyTeam.Group.Battle.GetRandom(list);
            //int index = 0;
            //do
            //{
            //    index = MyTeam.random.Next(0, 6);
            //    Pokemon pm = MyTeam.Pokemon[index];
            //    if (MyTeam.Pokemon.Count > 6 && object.ReferenceEquals(this, MyTeam.SelectedPokemon[1]))
            //    {
            //        pm = MyTeam.Pokemon[index + 6];
            //    }
            //    if (pm != null && pm.HealthPower != 0 && !MyTeam.SelectedPokemon.Contains(pm))
            //        break; // TODO: might not be correct. Was : Exit Do
            //} while (true);
            MyTeam.log.AppendMsg("ForceWithdraw", this.GetNameString());
            //MyTeam.log.AddText(GetNameString() + "强制下场！");
            MyTeam.Group.ChangePM(this, p2, false);
            //MyTeam.Group.ChangePokemon(this, index + 1, false);
            return true;
        }

        /// <summary>
        /// 发动替身
        /// </summary>
        /// <returns></returns>
        public bool MakeSubstitute()
        {
            if (BattleState.substituted)
            {
                MyTeam.log.AppendMsg("HasSubstitute", this.GetNameString());
                return false;
            }

            int hp = Math.Max(1, (int)Math.Truncate(MaxHp * 0.25));
            if (HealthPower <= hp)
            {
                MyTeam.log.AppendMsg("NoHp4Substitute");
                return false;
            }

            this.GetHurt(hp);
            BattleState.substituted = true;
            BattleState.subHP = hp;
            MyTeam.log.AppendMsg("EnSubstitute", this.GetNameString());
            //MyTeam.log.AddText(GetNameString() + "制造了一个替身！");
            if (BattleState.constraint && BattleState.constraintTurn != -1)
            {
                MyTeam.log.AppendMsg("DeDisable", this.GetNameString());
                //MyTeam.log.AddText(GetNameString() + "解除了束缚！");
                BattleState.constraint = false;
                BattleState.constraintTurn = 0;
            }
            OnImageChanged();
            return true;
        }

        /// <summary>
        /// 咩歌
        /// </summary>
        public void PerishSong()
        {
            if (!BattleState.perishSong)
            {
                BattleState.perishSong = true;
                BattleState.perishSongCounter = 4;
            }
        }
    }
}